package com.bigdata.auth;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;

/**
 * @author xin.ding
 * @date 2020/11/11 17:38
 */
public class JaasFactory {
    private static Logger logger = LoggerFactory.getLogger(JaasFactory.class);

    private static String loginModule = getKrb5LoginModuleName();

    /**
     * 生成jaas文件
     *
     * @param type      组件类型
     * @param principal kerberos principal名称
     * @param keytab    kerberos keytab文件
     * @return 临时jaas文件路径
     */
    public static String buildJaasFile(SourceType type, String principal, String keytab) {
        File file = generateConfigFile();

        List<String> lines = new ArrayList<>(16);

        if (type == SourceType.KAFKA) {
            lines.add("KafkaClient {");
        } else if (type == SourceType.HBASE) {
            lines.add("HbaseClient {");
        } else if (type == SourceType.HIVE) {
            lines.add("com.sun.security.jgss.krb5.initiate {");
        }

        lines.add(" " + loginModule + " required");
        if (type == SourceType.HBASE) {
            lines.add(" serviceName=\"kafka\"");
        }
        lines.add(" useTicketCache=true");
        lines.add(" useKeyTab=true");
        lines.add(" principal=\"" + principal + "\"");
        lines.add(" keyTab=\"" + keytab + "\";");
        lines.add("};");

        lines.add("Client {");
        lines.add(" " + loginModule + " required");
        lines.add(" useTicketCache=true");
        lines.add(" useKeyTab=true");
        lines.add(" principal=\"" + principal + "\"");
        lines.add(" keyTab=\"" + keytab + "\";");
        lines.add("};");

        try (FileWriter fw = new FileWriter(file.getAbsoluteFile(), true);) {
            fw.append(StringUtils.join(lines, "\n"));
        } catch (IOException e) {
            throw new AuthException("unable to generate a JAAS configuration file", e);
        }

        logger.debug("kerberos jass file {}", file.getAbsolutePath());
        return file.getAbsolutePath();
    }

    /**
     * Generate the default JAAS config file.
     */
    private static File generateConfigFile() {
        final File jaasConfFile;
        try {
            Path jaasConfPath = Files.createTempFile("jaas-", ".conf");
            jaasConfFile = jaasConfPath.toFile();
            jaasConfFile.deleteOnExit();
        } catch (IOException e) {
            throw new AuthException("unable to generate a JAAS configuration file", e);
        }
        return jaasConfFile;
    }

    /**
     * 获取kerberos login module
     */
    private static String getKrb5LoginModuleName() {
        return System.getProperty("java.vendor").contains("IBM")
                ? "com.ibm.security.auth.module.Krb5LoginModule"
                : "com.sun.security.auth.module.Krb5LoginModule";
    }
}
